package com.kingint.web.portal.serve.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.kingint.mbg.bas.entity.BasDepartment;
import com.kingint.mbg.dto.BackQueryParam;
import com.kingint.mbg.dto.MemberReturn;
import com.kingint.mbg.ser.entity.SerMessageReplyMiddle;
import com.kingint.mbg.ser.entity.SerSendMessage;
import com.kingint.mbg.ser.entity.SerWorkOrder;
import com.kingint.mbg.ser.mapper.SerMessageReplyMiddleMapper;
import com.kingint.mbg.ser.mapper.SerSendMessageMapper;
import com.kingint.mbg.ser.mapper.SerWorkOrderMapper;
import com.kingint.mbg.sys.entity.UmsMember;
import com.kingint.mbg.sys.mapper.UmsMemberMapper;
import com.kingint.web.portal.base.service.DepartmentService;
import com.kingint.web.portal.data.service.DataWorkOrderService;
import com.kingint.web.portal.serve.service.ActivitiCancelService;
import com.kingint.web.portal.serve.service.SendMessageService;
import com.kingint.web.sys.service.UmsAdminService;
import com.kingint.web.util.CharUtil;
import com.kingint.web.util.WorkType;
import com.kingint.web.util.WorkTypeUtil;
import com.kingint.web.vo.CountParam;
import com.kingint.web.vo.MessageBean;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.TaskService;
import org.activiti.engine.task.Task;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class SendMessageServiceImpl implements SendMessageService {

    @Resource
    private UmsAdminService adminService;
    @Resource
    private SerWorkOrderMapper workOrderMapper;
    @Resource
    private SerSendMessageMapper sendMessageMapper;
    @Resource
    private DepartmentService departmentService;
    @Resource
    private UmsMemberMapper memberMapper;
    @Resource
    private SerMessageReplyMiddleMapper messageReplyMiddleMapper;
    @Resource
    private ActivitiCancelService activitiCancelService;
    @Resource
    private MessageBean messageBean;
    @Resource
    private TaskService taskService;
    @Resource
    private DataWorkOrderService dataWorkOrderService;

    @Override
    public int insertSendMessageInfo(SerSendMessage serSendMessage) {
        UmsMember currentMember = adminService.getCurrentMember();
        Integer hotelId = currentMember.getHotelId();
        if (StringUtils.isEmpty(hotelId)) {
            log.debug("该账号没有关联酒店id");
            return 0;
        }
        //进行相关的处理
        SerWorkOrder workOrder = new SerWorkOrder();
        workOrder.setHotelId(hotelId);//对应酒店
        workOrder.setSubmitUserId(currentMember.getId());//提交人员
        workOrder.setOrderSn(CharUtil.generateOrderSn());//工单号
        //查询工单类型
        Integer typeId = WorkTypeUtil.getWorkTypeIdByName(WorkType.sendMessageName);
        workOrder.setWorkTypeId(typeId);
        workOrder.setCreateTime(new Date());//创建时间
        //插入总工单中
        int insert = workOrderMapper.insert(workOrder);

        //插入群发通知工单中
        serSendMessage.setCreateTime(new Date());
        serSendMessage.setWorkId(workOrder.getId());
        sendMessageMapper.insert(serSendMessage);

        //查询相关人员，添加回复人员中间表
        //0,部门全选，1，对应部门下人全选，2.对应部门下的某些人
        Integer sendTyp = serSendMessage.getSendTyp();
        if (sendTyp == 0) {//查询对应酒店下的所有部门信息
            List<BasDepartment> list = departmentService.getDepartmentListByHotelId(hotelId);
            if (!CollectionUtils.isEmpty(list)) {
                handleSelectDepartment(list, serSendMessage.getId());
            }
        } else if (sendTyp == 1) {//选择多个部门
            List<BasDepartment> departmentList = serSendMessage.getDepartmentList();
            if (!CollectionUtils.isEmpty(departmentList)) {
                handleSelectDepartment(departmentList, serSendMessage.getId());
            }
        } else if (sendTyp == 2) {
            List<MemberReturn> list = serSendMessage.getMemberReturnList();
            if (!CollectionUtils.isEmpty(list)) {
                handleUserList(list, serSendMessage.getId());
            }
        }
        String businessKey = messageBean.getProcessInstanceKey() + "_" + currentMember.getHotelId() + "_" + workOrder.getId();//业务相关参数

        //启动相关流程
        HashMap<String, Object> map = new HashMap<>();
        map.put(messageBean.getCreateNameEl(), currentMember.getUsername());
        String processInstanceId = activitiCancelService.startProcess(messageBean.getProcessInstanceKey(), businessKey, map);
        workOrder.setProcessInstanceId(processInstanceId);
        workOrder.setOrderStatus(5);
        workOrderMapper.updateById(workOrder);
        //完成相关的任务

        Task task = taskService.createTaskQuery()
                .processInstanceId(processInstanceId)
                .singleResult();
        taskService.complete(task.getId());
        //总工单
        dataWorkOrderService.addwork(currentMember.getHotelId(), CountParam.SENDMESSAGECOUNT);
        return insert;
    }

    @Override
    public List<SerSendMessage> unConfirmMessage() {
        UmsMember currentMember = adminService.getCurrentMember();
        Integer hotelId = currentMember.getHotelId();
        if (StringUtils.isEmpty(hotelId)) {
            log.debug("该账号未关联对应的酒店id");
            return null;
        }
        List<SerSendMessage> list = sendMessageMapper.getMessageListByUserId(currentMember.getId(), 0);
        return list;
    }

    @Override
    public List<SerSendMessage> confirmMessage() {
        UmsMember currentMember = adminService.getCurrentMember();
        Integer hotelId = currentMember.getHotelId();
        if (StringUtils.isEmpty(hotelId)) {
            log.debug("该账号未关联对应的酒店id");
            return null;
        }
        List<SerSendMessage> list = sendMessageMapper.getMessageListByUserId(currentMember.getId(), 1);
        return list;
    }

    @Override
    public SerSendMessage queryDetails(Integer id) {
        UmsMember currentMember = adminService.getCurrentMember();
        SerSendMessage message = sendMessageMapper.selectById(id);
        //处理用户是否已经回复以及选择的总人数
        QueryWrapper<SerMessageReplyMiddle> wrapper = new QueryWrapper<>();
        wrapper.eq("send_message_id", message.getId());
        //查询中间表信息
        List<SerMessageReplyMiddle> middles = messageReplyMiddleMapper.selectList(wrapper);

        //查询详情时修改当前用户的阅读状态
        wrapper.eq("receive_user_id", currentMember.getId());
        SerMessageReplyMiddle replyMiddle = new SerMessageReplyMiddle();
        replyMiddle.setIsRead(1);
        messageReplyMiddleMapper.update(replyMiddle, wrapper);

        if (!CollectionUtils.isEmpty(middles)) {
            List<Long> collect = middles.stream().map(s -> {
                return s.getReceiveUserId();
            }).collect(Collectors.toList());
            //查询当前的用户信息
            List<MemberReturn> listById = memberMapper.getAllMemberListById(collect);
            message.setMemberReturnList(listById);//群发通知当前有的人员

            middles.stream().forEach(s -> {
                List<MemberReturn> collect1 = listById.stream().filter(s1 -> s1.getId().equals(s.getReceiveUserId())).collect(Collectors.toList());
                if (collect1.size() != 0) {
                    s.setUsername(collect1.get(0).getUsername());
                    s.setIcon(collect1.get(0).getIcon());
                }
            });
        }
        //处理未读，已读
        message.setMessageReplyMiddleList(middles);
        return message;
    }

    @Override
    public Integer confirmReply(Integer id) {
        UmsMember currentMember = adminService.getCurrentMember();
        QueryWrapper<SerMessageReplyMiddle> wrapper = new QueryWrapper<>();
        wrapper.eq("receive_user_id", currentMember.getId())
                .eq("send_message_id", id);
        SerMessageReplyMiddle middle = new SerMessageReplyMiddle();
        middle.setReply(1);
        int update = messageReplyMiddleMapper.update(middle, wrapper);
        return update;
    }

    @Override
    public IPage<SerSendMessage> getSendMessageList(Integer pageNum, Integer pageSize) {
        UmsMember currentMember = adminService.getCurrentMember();
        Integer hotelId = currentMember.getHotelId();
        if (StringUtils.isEmpty(hotelId)) {
            log.debug("该账号未关联对应的酒店id");
            return null;
        }
        IPage<SerSendMessage> page=new Page<>(pageNum,pageSize);
        //相关的群发通知的参数
        BackQueryParam param = new BackQueryParam();
        param.setHotelId(hotelId);
        param.setReceiveUserId(currentMember.getId());
        IPage<SerSendMessage> list = sendMessageMapper.getFrontSendMessageList(page, param);
        return list;
    }

    /**
     * 处理相关的信息
     *
     * @param list
     * @param id
     */
    private void handleUserList(List<MemberReturn> list, Integer id) {
        list.stream().forEach(s -> {
            SerMessageReplyMiddle middle = new SerMessageReplyMiddle();
            middle.setCreateTime(new Date());
            middle.setReceiveUserId(s.getId());
            middle.setSendMessageId(id);
            middle.setIsRead(0);
            messageReplyMiddleMapper.insert(middle);
        });
    }

    /**
     * 处理选择的部门
     *
     * @param departmentList
     * @param id
     */
    private void handleSelectDepartment(List<BasDepartment> departmentList, Integer id) {
        //查询每个部门下的人
        new Thread(new Runnable() {
            @Override
            public void run() {
                List<Integer> collect = departmentList.stream().map(BasDepartment::getId).collect(Collectors.toList());
                QueryWrapper<UmsMember> wrapper = new QueryWrapper<>();
                wrapper.in("department_id", collect);
                List<UmsMember> umsMembers = memberMapper.selectList(wrapper);
                if (umsMembers.size() != 0) {
                    List<Long> collect1 = umsMembers.stream().map(UmsMember::getId).collect(Collectors.toList());
                    //插入相关的信息
                    collect1.stream().forEach(s -> {
                        SerMessageReplyMiddle middle = new SerMessageReplyMiddle();
                        middle.setCreateTime(new Date());
                        middle.setReceiveUserId(s);
                        middle.setSendMessageId(id);
                        middle.setIsRead(0);
                        messageReplyMiddleMapper.insert(middle);
                    });
                }
            }
        }).start();

    }
}
